<template>
  <div id="app" style="padding: 16px;">
    <el-divider content-position="left">模型文件基础信息</el-divider>
    <el-form v-if="form" ref="form" :model="form" label-width="140px">
      <el-row>
        <el-col :span="5" :offset="2">
          <el-form-item label="作者">
            <el-tooltip class="item" effect="dark" :content="form.author" placement="top-start">
              <el-input v-model="form.author" size="small"/>
            </el-tooltip>
          </el-form-item>
        </el-col>

        <el-col :span="5">
          <el-form-item label="邮箱">
            <el-tooltip class="item" effect="dark" :content="form.email" placement="top-start">
              <el-input v-model="form.email" size="small"/>
            </el-tooltip>
          </el-form-item>
        </el-col>

        <el-col :span="5" :offset="2">
          <el-form-item label="模块名">
            <el-tooltip class="item" effect="dark" :content="form.model_name" placement="top-start">
              <el-input v-model="form.model_name" @input="inputModelName" @change="changeModelName" size="small"/>
            </el-tooltip>
          </el-form-item>
        </el-col>

        <el-col :span="5">
          <el-form-item label="文件名">
            <el-tooltip class="item" effect="dark" :content="form.file_name" placement="top-start">
              <el-input v-model="form.file_name" size="small"/>
            </el-tooltip>
          </el-form-item>
        </el-col>
      </el-row>

      <el-divider content-position="left">导入包列表</el-divider>
      <el-row>
        <div v-for="(pkg, pkg_index) in form.import_pkg_list" :key="pkg_index">
          <el-col :span="2" style="padding-left: 16px;">
            <el-button type="primary" icon="el-icon-plus" circle size="mini" @click="addImportPkg"/>
            <el-button type="danger" icon="el-icon-minus" circle size="mini" @click="delImportPkg(pkg_index)"/>
          </el-col>

          <el-col :span="5">
            <el-form-item label="导入位置(from)">
              <el-tooltip class="item" effect="dark" :content="pkg.from" placement="top-start">
                <el-input v-model="pkg.from" size="small"/>
              </el-tooltip>
            </el-form-item>
          </el-col>
          <el-col :span="5">
            <el-tooltip class="item" effect="dark" :content="pkg.import" placement="top-start">
              <el-form-item label="导入内容(import)">
                <el-input v-model="pkg.import" size="small"/>
              </el-form-item>
            </el-tooltip>
          </el-col>
        </div>
      </el-row>
      <el-divider content-position="left">参数类</el-divider>
      <!-- 参数类-->
      <div v-for="(schema, schema_index) in form.schema_classes" :key="schema_index">
        <el-row>
          <el-col :span="2" style="padding-left: 16px;">
            <el-button type="primary" icon="el-icon-plus" circle size="mini" @click="addSchemaClass"/>
            <el-button type="danger" icon="el-icon-minus" circle size="mini" @click="delSchemaClass(schema_index)"/>
          </el-col>

          <el-col :span="5">
            <el-form-item label="参数类名">
              <el-tooltip class="item" effect="dark" :content="schema.name" placement="top-start">
                <el-input v-model="schema.name" size="small"/>
              </el-tooltip>
            </el-form-item>
          </el-col>

          <el-col :span="5">
            <el-form-item label="父类名称">
              <el-tooltip class="item" effect="dark" :content="schema.parent_class" placement="top-start">
                <el-input v-model="schema.parent_class" size="small"/>
              </el-tooltip>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 是否存在字段-->
        <el-row>
          <el-col :span="5" :offset="2">
            <el-form-item label="省略内容">
              <el-switch
                v-model="schema.is_pass"
                active-color="#13ce66"
                inactive-color="#ff4949"
                @change="changeIsPass(schema.is_pass, schema_index)">
              </el-switch>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 参数类字段信息-->
        <div v-for="(field, field_index) in schema.fields" :key="field_index">
          <el-row>
            <el-col :span="2" style="padding-left: 16px;" :offset="5">
              <el-button type="primary" icon="el-icon-plus" circle size="mini"
                         @click="addSchemaClassField(schema_index)"/>
              <el-button type="danger" icon="el-icon-minus" circle size="mini"
                         @click="delSchemaClassField(schema_index, field_index)"/>
            </el-col>

            <el-col :span="5">
              <el-form-item label="字段名称">
                <el-tooltip class="item" effect="dark" :content="field.field_name" placement="top-start">
                  <el-input v-model="field.field_name" size="small"/>
                </el-tooltip>
              </el-form-item>
            </el-col>

            <el-col :span="5" :offset="2">
              <el-form-item label="字段类型">
                <el-tooltip class="item" effect="dark" :content="field.field_type" placement="top-start">
                  <el-input v-model="field.field_type" size="small"/>
                </el-tooltip>
              </el-form-item>
            </el-col>

            <el-col :span="5">
              <el-form-item label="是否可选">
                <el-tooltip class="item" effect="dark" :content="field.optional.toString()" placement="top-start">
                  <el-select v-model="field.optional" placeholder="是否可选" filterable size="small">
                    <el-option v-for="(item, index) in isOptional" :key="index" :label="item.label"
                               :value="item.value"/>
                  </el-select>
                  <el-input v-model="field.field_type" size="small"/>
                </el-tooltip>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row v-for="(attr, attr_index) in field.attrs" :key="attr_index">
            <el-col :span="2" style="padding-left: 16px;" :offset="12">
              <el-button type="primary" icon="el-icon-plus" circle size="mini"
                         @click="addSchemaFieldAttr(schema_index, field_index)"/>
              <el-button type="danger" icon="el-icon-minus" circle size="mini"
                         @click="delSchemaFieldAttr(schema_index, field_index, attr_index)"/>
            </el-col>

            <el-col :span="5">
              <el-form-item label="属性名称">
                <el-tooltip class="item" effect="dark" :content="attr.attr_name" placement="top-start">
                  <el-input v-model="attr.attr_name" size="small"/>
                </el-tooltip>
              </el-form-item>
            </el-col>

            <el-col :span="5">
              <el-form-item label="属性值">
                <el-tooltip class="item" effect="dark" :content="attr.attr_value" placement="top-start">
                  <el-input v-model="attr.attr_value" size="small"/>
                </el-tooltip>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
        <el-row>
          <el-col :span="5" :offset="2">
            <el-form-item label="存在子类">
              <el-switch
                v-model="schema.exist_meta"
                active-color="#13ce66"
                inactive-color="#ff4949"
                @change="changeExistMeta(schema.exist_meta, schema_index)">
              </el-switch>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 参数类的子类信息-->
        <div v-if="schema.meta_class != null">
          <el-row>
            <el-col :span="5" :offset="2">
              <el-form-item label="子类名">
                <el-tooltip class="item" effect="dark" :content="schema.meta_class.name" placement="top-start">
                  <el-input v-model="schema.meta_class.name" size="small"/>
                </el-tooltip>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-for="(field, field_index) in schema.meta_class.fields" :key="field_index">
            <el-col :span="2" style="padding-left: 16px;" :offset="5">
              <el-button type="primary" icon="el-icon-plus" circle size="mini"
                         @click="addMetaField(schema_index)"/>
              <el-button type="danger" icon="el-icon-minus" circle size="mini"
                         @click="delMetaField(schema_index, field_index)"/>
            </el-col>

            <el-col :span="5">
              <el-form-item label="子类字段属性名">
                <el-tooltip class="item" effect="dark" :content="field.name" placement="top-start">
                  <el-input v-model="field.name" size="small"/>
                </el-tooltip>
              </el-form-item>
            </el-col>

            <el-col :span="5">
              <el-form-item label="子类字段属性值">
                <el-tooltip class="item" effect="dark" :content="field.value" placement="top-start">
                  <el-input v-model="field.value" size="small"/>
                </el-tooltip>
              </el-form-item>
            </el-col>
          </el-row>
        </div>

      </div>

      <el-form-item>
        <el-button type="primary" @click="onSubmit" size="mini">生成</el-button>
        <el-button type="danger" @click="resetConfig" size="mini">恢复</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import interfaceObj from '../../api/schema'

export default {
  data () {
    return {
      form: null,
      isPassOptions: [
        {
          value: 'true',
          label: 'true'
        },
        {
          value: 'false',
          label: 'false'
        }
      ],
      isOptional: [
        {
          value: 'true',
          label: 'true'
        },
        {
          value: 'false',
          label: 'false'
        }
      ]
    }
  },
  mounted () {
    this.resetConfig()
  },
  computed: {
    getAttrOffset () {
      return function (attrIndex) {
        if (attrIndex !== 0) {
          return 12
        }
      }
    }
  },
  methods: {
    addImportPkg () {
      this.form.import_pkg_list.push({
        from: '',
        pkg: ''
      })
    },
    delImportPkg (fieldIndex) {
      if (this.form.import_pkg_list.length === 1) {
        this.$message({
          message: '至少导入一个包'
        })
        return
      }
      this.form.import_pkg_list.splice(fieldIndex, 1)
    },
    addSchemaClass () {
      this.form.schema_classes.push({
        name: 'NewSchemaClass',
        parent_class: 'NewSchemaClassParentClass',
        is_pass: true,
        fields: [
          {
            optional: true,
            field_name: 'id',
            field_type: 'str',
            attrs: [
              {
                attr_value: 'None'
              },
              {
                attr_name: 'title',
                attr_value: '""'
              }
            ]
          }
        ],
        meta_class: null
      })
    },
    delSchemaClass (schemaIndex) {
      if (this.form.schema_classes.length === 1) {
        this.$message({
          message: '最少一个字段',
          type: 'warning'
        })
        return
      }
      this.form.schema_classes.splice(schemaIndex, 1)
    },
    addSchemaClassField (schemaIndex) {
      this.form.schema_classes[schemaIndex].fields.push({
        optional: true,
        field_name: 'id',
        field_type: 'str',
        attrs: [
          {
            attr_value: 'None'
          },
          {
            attr_name: 'title',
            attr_value: '""'
          }
        ]
      })
    },
    delSchemaClassField (schemaIndex, fieldIndex) {
      if (this.form.schema_classes[schemaIndex].fields.length === 1) {
        this.$message({
          message: '每个参数对象最少一个字段',
          type: 'warning'
        })
        return
      }
      this.form.schema_classes[schemaIndex].fields.splice(fieldIndex, 1)
    },
    addSchemaFieldAttr (schemaIndex, fieldIndex) {
      this.form.schema_classes[schemaIndex].fields[fieldIndex].attrs.push({
        name: 'NewSchemaClass',
        parent_class: 'NewSchemaClassParentClass',
        is_pass: true,
        fields: [],
        meta_class: null
      })
    },
    delSchemaFieldAttr (schemaIndex, fieldIndex, attrIndex) {
      if (this.form.schema_classes[schemaIndex].fields[fieldIndex].attrs.length === 1) {
        this.$message({
          message: '每个字段最少一个属性',
          type: 'warning'
        })
        return
      }
      this.form.schema_classes[schemaIndex].fields[fieldIndex].attrs.splice(attrIndex, 1)
    },
    addMetaField (schemaIndex) {
      this.form.schema_classes[schemaIndex].meta_class.fields.push({
        name: 'orm_mode',
        value: 'True'
      })
    },
    delMetaField (schemaIndex, fieldIndex) {
      if (this.form.schema_classes[schemaIndex].meta_class.fields.length === 1) {
        this.$message({
          message: '子类最少一个字段',
          type: 'warning'
        })
        return
      }
      this.form.schema_classes[schemaIndex].meta_class.fields.splice(fieldIndex, 1)
    },
    addAttr (fieldIndex) {
      this.form.fields[fieldIndex].attrs.push({
        key: '',
        value: ''
      })
    },
    delAttr (fieldIndex, attrIndex) {
      if (this.form.fields[fieldIndex].attrs.length === 1) {
        this.$message({
          message: '每个字段最少一个属性',
          type: 'warning'
        })
        return
      }
      this.form.fields[fieldIndex].attrs.splice(attrIndex, 1)
    },
    inputModelName (content) {
      const wordList = content.match(/[A-Z][a-z]+/g)
      let filename = ''
      if (wordList !== null) {
        wordList.forEach((item, index) => {
          if (index !== (wordList.length - 1)) {
            filename = filename + item.toLowerCase() + '_'
          } else {
            filename = filename + item.toLowerCase()
          }
        })
        this.form.file_name = filename
      }
    },
    changeModelName (content) {
      // 循环参数类，将Model改为输入后的模块类名
      for (let i = 0; i < this.form.schema_classes.length; i++) {
        const item = this.form.schema_classes[i]
        // 替换schema_class name
        if (item.name.indexOf('Model') !== -1) {
          item.name = item.name.replace('Model', content)
        }
        // 替换schema_class parent_class
        if (item.parent_class.indexOf('Model') !== -1 && item.parent_class !== 'BaseModel') {
          item.parent_class = item.parent_class.replace('Model', content)
        }
        // 循环schema_class 中的 fields 替换 field_type
        for (let j = 0; j < item.fields.length; j++) {
          if (item.fields[j].field_type.indexOf('Model') !== -1) {
            console.log('type')
            item.fields[j].field_type = item.fields[j].field_type.replace('Model', content)
          }
        }
      }
    },
    // 切换是否省略
    changeIsPass (value, schemaIndex) {
      this.form.schema_classes[schemaIndex].is_pass = value
      if (value) {
        this.form.schema_classes[schemaIndex].fields = []
        this.form.schema_classes[schemaIndex].exist_meta = false
        this.form.schema_classes[schemaIndex].meta_class = null
      } else {
        this.form.schema_classes[schemaIndex].fields.push({
          optional: true,
          field_name: 'id',
          field_type: 'str',
          attrs: [
            {
              attr_value: 'None'
            },
            {
              attr_name: 'title',
              attr_value: '""'
            }
          ]
        })
        this.form.schema_classes[schemaIndex].exist_meta = true
        this.form.schema_classes[schemaIndex].meta_class = {
          name: 'Config',
          fields: [
            {
              name: 'orm_mode',
              value: 'True'
            }
          ]
        }
      }
    },
    // 切换是否存在子类
    changeExistMeta (value, schemaIndex) {
      if (value) {
        this.form.schema_classes[schemaIndex].meta_class = {
          name: 'Config',
          fields: [
            {
              name: 'orm_mode',
              value: 'True'
            }
          ]
        }
      } else {
        this.form.schema_classes[schemaIndex].meta_class = null
      }
    },
    onSubmit () {
      interfaceObj.generateSchema(this.form).then(res => {
        console.log(res)
      })
    },
    resetConfig () {
      const ignoreField = ['id', 'add_datetime', 'update_datetime', 'is_active']
      this.$axios.get('/schema_param.json').then(res => {
        this.form = res.data.form
        // 根据model生成设置的字段
        this.$store.state.modelFields.forEach(item => {
          if (item.field_name in ignoreField) {
            return true
          } else {
            // 类型
            let fieldType
            switch (item.field_type_class) {
              case 'Float':
                fieldType = 'float'
                break
              case 'Boolean':
                fieldType = 'bool'
                break
              case 'Integer':
                fieldType = 'int'
                break
              case 'DateTime':
                fieldType = 'datetime'
                break
              case 'ARRAY(String)':
                fieldType = 'List[str]'
                break
              case 'ARRAY(Float)':
                fieldType = 'List[float]'
                break
              case 'ARRAY(Integer)':
                fieldType = 'List[int]'
                break
              case 'ARRAY(Boolean)':
                fieldType = 'List[bool]'
                break
              default:
                fieldType = 'str'
                break
            }
            // 注释
            let comment = '说明'
            item.attrs.forEach(itemAttr => {
              if (itemAttr.key === 'comment') {
                comment = itemAttr.value
              }
            })
            // BaseModel
            this.form.schema_classes[0].fields.push({
              optional: true,
              field_name: item.field_name,
              field_type: fieldType,
              attrs: [
                {
                  attr_name: 'description',
                  attr_value: comment
                }
              ]
            })
          }
        })
        this.form.author = this.$store.state.author
        this.form.email = this.$store.state.email
        this.form.model_name = this.$store.state.moduleName
        this.inputModelName(this.form.model_name)
        this.changeModelName(this.form.model_name)
      })
    }
  }
}
</script>

<style>

</style>
